/*
 * Copyright 2002-2006 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.jwtools.tmt.ui.table;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JTable;
import javax.swing.table.TableColumnModel;

import net.jwtools.tmt.domain.IVisit;
import net.jwtools.tmt.service.IVisitService;
import net.jwtools.tmt.service.VisitService;
import net.jwtools.tmt.ui.renderer.DateTableCellRenderer;

import org.springframework.context.ApplicationEvent;
import org.springframework.richclient.application.event.LifecycleApplicationEvent;
import org.springframework.richclient.command.ActionCommandExecutor;
import org.springframework.richclient.table.support.AbstractObjectTable;

/**
 * This class provides a concrete implementation of a table showing
 * {@link Visit} objects.
 * 
 * @author Naftali van der Loon
 */
public class VisitsTable extends AbstractObjectTable {
	private ActionCommandExecutor clickHandler;
	/**
	 * Default constructor.
	 */
	public VisitsTable() {
		super("visits", new String[] {"territory.number",
				"checkoutDate", "endDate", "totalDaysCheckedout", "checkoutBy.displayName", "notHomeNumber" });
	}

	protected void configureTable(JTable table) {
		// Adjust the table column widths
		TableColumnModel tcm = table.getColumnModel();
		tcm.getColumn(0).setPreferredWidth(20);
		tcm.getColumn(1).setPreferredWidth(70);
		tcm.getColumn(1).setCellRenderer(new DateTableCellRenderer(getMessage("dateformat")));
		tcm.getColumn(2).setPreferredWidth(70);
		tcm.getColumn(2).setCellRenderer(new DateTableCellRenderer(getMessage("dateformat")));
		tcm.getColumn(4).setPreferredWidth(100);
		tcm.getColumn(4).setPreferredWidth(100);
		table.addMouseListener(new DetailsUpdateListener());
	}

	/**
	 * Provide the initial data for the table. Note that this is hard coded for
	 * this sample. You would normally access a persistent store, or some other
	 * source to get the data for the table.
	 */
	protected Object[] getDefaultInitialData() {
		return ((IVisitService)getService(VisitService.class)).getAllCompleted().toArray();
	}

	/**
	 * Get the array of selected Contact objects in the table.
	 * 
	 * @return array of Contacts, zero length if nothing is selected
	 */
	public IVisit[] getSelectedVisits() {
		int[] selected = getTable().getSelectedRows();
		IVisit[] visits = new IVisit[selected.length];
		for (int i = 0; i < selected.length; i++) {
			visits[i] = (IVisit) getTableModel().getElementAt(selected[i]);
		}
		return visits;
	}

	public IVisit getSelectedVisit() {
		IVisit selected = null;
		if (getTable().getSelectedRow()>=0) selected = (IVisit) getTableModel().getElementAt(getTable().getSelectedRow()); 
		return selected;
	}

	@Override
	protected int getInitialSortColumn() {
		// TODO Auto-generated method stub
		return 1;
	}
	
	@Override
	protected boolean isMultipleColumnSort() {
		return false;
	}

	final class DetailsUpdateListener extends MouseAdapter {
		@Override
		public void mouseClicked(MouseEvent e) {
			// If the user double clicked on a row, then call onDoubleClick
			if (e.getClickCount() == 1) {
				clickHandler.execute();
			}
		}
	}

	public ActionCommandExecutor getClickHandler() {
		return clickHandler;
	}

	public void setClickHandler(ActionCommandExecutor clickHandler) {
		this.clickHandler = clickHandler;
	}
	
	/**
	 * Handle an application event. This will notify us of object adds, deletes, and modifications. Update our table
	 * model accordingly.
	 * @param e event to process
	 */
	public void onApplicationEvent(ApplicationEvent e) {
		if (e instanceof LifecycleApplicationEvent) {
			LifecycleApplicationEvent le = (LifecycleApplicationEvent) e;
			if (shouldHandleEvent(e)) {
				IVisit eventObject = (IVisit)le.getObject();
				logger.debug("VisitsTable got "+le.getEventType()+" for "+eventObject.getId()+"="+eventObject);
				if (le.getEventType() == LifecycleApplicationEvent.CREATED) {
					if (eventObject.getCheckinDate()!=null) {
						handleNewObject(eventObject);
					} else {
						handleDeletedObject(eventObject);
					}
				}
				else if (le.getEventType() == LifecycleApplicationEvent.MODIFIED) {
					handleUpdatedObject(le.getObject());
				}
				else if (le.getEventType() == LifecycleApplicationEvent.DELETED) {
					handleDeletedObject(le.getObject());
				}
			}
		}
	}

}
